//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using System;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace LargoCommon.Music
{
/// Harmonic transfer.
///
/// Is prototype for computation of characteristics needed
/// by harmonic state and harmonic relation classes.
[Serializable]
[XmlRoot]
public class HarmonicTransfer {
#region Fields
///
/// Harmonic system.
///
private readonly HarmonicSystem harSystem;
/// List of musical intervals.
private readonly Collection intervals;
#endregion
#region Constructors
/// Initializes a new instance of the HarmonicTransfer class. Serializable.
public HarmonicTransfer() {
}
///
/// Initializes a new instance of the HarmonicTransfer class.
///
/// The given system.
public HarmonicTransfer(HarmonicSystem givenSystem) {
Contract.Requires(givenSystem != null);
this.harSystem = givenSystem;
this.intervals = new Collection();
}
#endregion
#region Properties
/// Gets the property.
/// Property description.
public float FormalContinuity { get; private set; }
/// Gets the property.
/// Property description.
public float FormalImpulse { get; private set; }
/// Gets the property.
/// Property description.
public float FormalPotential { get; private set; }
/// Gets the property.
/// Property description.
public float FormalConsonance { get; private set; }
/// Gets harmonic system.
/// Property description.
[XmlIgnore]
public HarmonicSystem HarmonicSystem {
get {
Contract.Ensures(Contract.Result() != null);
if (this.harSystem == null) {
throw new InvalidOperationException("Harmonic system is null.");
}
return this.harSystem;
}
}
/// Gets list of musical intervals.
/// Property description.
[XmlIgnore]
public Collection Intervals {
get {
Contract.Ensures(Contract.Result>() != null);
if (this.intervals == null) {
throw new InvalidOperationException("List of intervals is null.");
}
return this.intervals;
}
}
#endregion
#region String representation
/// String representation of the object.
/// Returns value.
public override string ToString() {
var s = new StringBuilder();
s.AppendFormat("Harmonic transfer (order={0})", this.HarmonicSystem.Order);
return s.ToString();
}
#endregion
#region Public methods
///
/// Computes mean value of given property in bindings.
///
/// General musical property.
/// Positive values.
/// If set to true [eliminate zeroes].
///
/// Returns value.
///
[JetBrains.Annotations.PureAttribute]
public float MeanValueOfProperty(GenProperty property, bool positive, bool eliminateZeros) {
var v = 0f;
if (this.Intervals.Count == 0) {
return v;
}
var cnt = 0;
// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (var value in
from interval in this.intervals
where interval != null
select interval.ValueOfProperty(property))
{
if (eliminateZeros && (int)value == 0) {
continue;
}
v = positive && value < 0 ? v - value : v + value;
cnt++;
}
return cnt > 0 ? v / cnt : 0f;
}
/// Sets harmonic properties of the cluster.
public void SetFormalProperties() {
// float Level = (float)(Math.Sqrt(1+8*this.intervals.Count)+1)/2;
if (this.Intervals.Count == 0) {
return;
}
this.FormalContinuity = this.MeanValueOfProperty(GenProperty.InnerContinuity, false, true); //// 15.7.2013, was true
//// formalContinuity = formalContinuity*this.intervals.Count/Level;
this.FormalImpulse = this.MeanValueOfProperty(GenProperty.InnerImpulse, true, true);
//// formalImpulse = formalImpulse*this.intervals.Count/Level;
this.FormalPotential = this.MeanValueOfProperty(GenProperty.FormalPotentialInfluence, true, true);
this.FormalConsonance = HarmonicSystem.Consonance(this.FormalContinuity, this.FormalImpulse);
//// const float formalGenus = 0;
}
#endregion
}
}